<?php
/**
 * User: hda
 * Date: 2017/4/17
 * Time: 13:19
 * Progress: 50%
 */

namespace icontroller\admin;

use library\request\Agent;
use library\request\Ip;
use think\Cache;
use think\Config;
use think\Controller;
use think\Cookie;
use think\Request;
use think\Db;
use think\Loader;

abstract class AController extends Controller
{
    protected $request;

    function __construct()
    {
        parent::__construct();
        $this->request = Request::instance();

//        Cookie::set('admin', 1);

        //管理员信息
        $admin = $this->getAdmin();

        //管理权限验证并写日志
        $this->checkAuthority($admin);

        //管理菜单
        $admin_menu = $this->getCachePowserMenu(0, $admin['menus']);

//        var_dump($admin_menu);die;
        $this->assign('admin_menu', json_encode($admin_menu));


    }

    // <editor-fold defaultstate="collapsed" desc="获取管理菜单树">

    private function getCachePowserMenu($pid = 0, $power = null)
    {
        $admin_menu = Cache::get('admin_menu_true');
        if ($admin_menu) {
            return $admin_menu;
        } else {
            $admin_menu = $this->getPowerMenu($pid, $power);
            Cache::set('admin_menu_true', $admin_menu, 2);
            return $admin_menu;
        }
    }

    /**
     * 管理菜单树
     * @param int $pid
     * @return array
     */
    private function getPowerMenu($pid = 0, $power = null)
    {


        $where['m.parent_id'] = $pid;
        if (!empty($power)) {
            $where['m.id'] = ['in', $power];
        }
        $list = Db::name('admin_menu')->alias('m')->join('admin_power p', 'm.power_id=p.id', 'LEFT')->where($where)->order(['m.sort' => 'asc', 'm.id' => 'asc'])->field('m.*,p.module,p.controller,p.function')->select();

        $array_tree = array();
        foreach ($list as $m) {

            $array = array();
            $array['id'] = $m['id'];
            if ($pid > 0) {
                $array['parent_id'] = $m['parent_id'];
            }
            $array['name'] = 'menu' . $m['id'];
            $array['text'] = $m['name'];
            $array['icon'] = $m['icon'];
            //$array['icon'] = 'jstree-file';
            //$array['state'] = array('opened' => false);
            if ($m['url']) {
                $array['frame_url'] = $m['url'];
            } else {
                $url = $m['function'] ? url($m['module'] . '/' . $m['controller'] . '/' . $m['function']) : '#';
                $array['frame_url'] = $url;
            }
            $array_son = $this->getPowerMenu($m['id'], $power);

            if (count($array_son) > 0) {
                $array['children'] = array();
                $array['children'] = $array_son;
            }
            array_push($array_tree, $array);
        }

        return $array_tree;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="获取管理员信息">
    private function getAdmin()
    {
        $cookie_name = Config::get('const.cookie_name_admin');
        $cookie = Cookie::get($cookie_name);
        if ($cookie) {
            $admin = Db::name('admin')->alias('a')->join('admin_role r', 'a.role_id=r.id', 'LEFT')->where(['a.id' => $cookie])->field('a.*,r.flag_lock as flag_lock_role,r.powers,r.menus')->find();

            return $admin;
        }else{
            $this->redirect('pub/login');
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="管理权限验证">

    private function checkAuthority($admin)
    {
        if ($admin) {
            if ($admin['role_id'] == 0 && $admin['nick'] == 'admin' && $admin['id'] == 1) {
                //超级管理员拥有所有权限
                $this->setAdminLog($admin['id'], 1);
            } else {
                $where['id'] = ['in', $admin['powers']];
                $list = Db::name('admin_power')->where($where)->select();
                $module = $this->request->module();
                $controller = strtolower($this->request->controller());
                $function = $this->request->action();

                $flag = false;
                foreach ($list as $menu) {
                    if ($menu['module'] == $module && strtolower($menu['controller']) == $controller && $menu['function'] == $function) {
                        $flag = true;
                        break;
                    }
                }
                if ($flag) {
                    //有权限
                    //$this->setAdminLog($admin['id'], 1);
                } else {
                    $this->setAdminLog($admin['id']);
                    $this->redirect('pub/lock');
                }
            }
        }else{
            $this->redirect('pub/login');
        }
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="记录管理日志">

    private function setAdminLog($admin_id, $flag_lawful = 0, $remark = null, $type = '2')
    {
        $data['type'] = $type;
        $data['admin_id'] = $admin_id;
        $data['ip'] = $this->request->ip();
//        $data['location'] = Ip::getLocation();
        $data['os'] = Agent::getOs();
        $data['browser'] = Agent::getBroswer();
        if (isset($_SERVER['HTTP_REFERER'])) {
            $data['http_referer'] = $_SERVER['HTTP_REFERER'];
        }
        $data['url'] = $this->request->domain() . $this->request->url();
        $data['module'] = $this->request->module();
        $data['controller'] = strtolower($this->request->controller());
        $data['function'] = $this->request->action();
        $data['method'] = $this->request->method();
        if (count($this->request->param()) > 0) {
            $data['request_param'] = json_encode($this->request->param());
        }
        $data['request_time'] = $this->request->time();
        $data['remark'] = $remark;
        $data['flag_lawful'] = $flag_lawful;
        Db::name('admin_log')->insertGetId($data);
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="默认更新字段方法">
    /**
     * 默认更新字段方法
     * @param string     $field 更新的字段
     * @param string|int $value 更新的值
     * @param string     $msg   操作成功提示信息
     * @param string     $pk    主键，默认为主键
     * @param string     $input 接收参数，默认为主键
     * @return string|\think\Response|\think\response\Json
     *
     */
    protected function updateField($field, $value, $msg = "操作成功", $pk = "", $input = "")
    {
        $model = $this->getModel();
        if (!$pk) {
            $pk = $model->getPk();
        }
        if (!$input) {
            $input = $model->getPk();
        }
        $ids = $this->request->param($input);
        $where[$pk] = ["in", $ids];
        if (false === $model->where($where)->update([$field => $value])) {
            return ajax_return_adv_error($model->getError());
        }
        return ajax_return_adv($msg, '');
    }

    /**
     * 获取模型
     *
     * @param string $controller
     * @param bool   $type 是否返回模型的类型
     *
     * @return \think\db\Query|\think\Model|array
     */
    protected function getModel($controller = '', $type = false)
    {
        $module = Config::get('app.model_path');
        if (!$controller) {
            $controller = $this->request->controller();
        }
        if (
            class_exists($modelClass = Loader::parseClass($module, 'model', $this->parseCamelCase($controller)))
            || class_exists($modelClass = Loader::parseClass($module, 'model', $controller))
        ) {
            $model = new $modelClass();
            $modelType = 'model';
        } else {
            $model = Db::name($this->parseTable($controller));
            $modelType = 'db';
        }

        return $type ? ['type' => $modelType, 'model' => $model] : $model;
    }

    /**
     * 将abc.def.Gh转为AbcDefGh
     *
     * @param $string
     *
     * @return mixed
     */
    protected function parseCamelCase($string)
    {
        return preg_replace_callback('/(\.|^)([a-zA-Z])/', function ($match) {
            return ucfirst($match[2]);
        }, $string);
    }

    /**
     * 格式化表名，将 /. 转为 _ ，支持多级控制器
     *
     * @param string $name
     *
     * @return mixed
     */
    protected function parseTable($name = '')
    {
        if (!$name) {
            $name = $this->request->controller();
        }

        return str_replace(['/', '.'], '_', $name);
    }
    // </editor-fold>
}